#pragma once

#include <io.h>
#include <gtl/io/file.h>
#include <gtl/string/str.h>

namespace gtl
{

class filefinder
{
public:
	filefinder() {
		m_hfind = 0;
		memset(&m_finfo, 0, sizeof(m_finfo));
	}

	~filefinder() {
		close();
	}

public:
	bool find(const TCHAR* path, const TCHAR* ext = _T("*.*")) {
		if(path == NULL)
			return false;

		_tchdir(path);
		m_path = path;
		if(m_path.back() != '\\')
			m_path += '\\';
		m_hfind = (long)_tfindfirst(ext, &m_finfo);
		return m_hfind != -1L;
	}

	bool next() {
		return _tfindnext(m_hfind, &m_finfo) == 0;
	}

	void close() {
		_findclose(m_hfind);
	}

	const TCHAR* get_file_name() {
		return m_finfo.name;
	}

	gtl::tstr get_file_path() {
		return m_path + m_finfo.name;
	}

	__int64 get_file_length() {
		return gtl::file(get_file_path(), _T("r")).length();
	}

	__int64 get_file_size() {
		return get_file_length();
	}

	bool is_dots() {
		return _tcscmp(m_finfo.name, _T(".")) == 0 || _tcscmp(m_finfo.name, _T("..")) == 0;
	}

	bool is_hidden() {
		return !!(m_finfo.attrib & _A_HIDDEN);
	}

	bool is_sys() {
		return !!(m_finfo.attrib & _A_SYSTEM);
	}

	bool is_dir() {
		return !!(m_finfo.attrib & _A_SUBDIR);
	}

	bool is_readonly() {
		return !!(m_finfo.attrib & _A_RDONLY);
	}

private:
	gtl::tstr m_path;
	long m_hfind;
	struct _tfinddata_t m_finfo;
};

} // end of namespace gtl